package com.ruoyi.common.service.impl;

import com.ruoyi.common.domain.po.BasePO;
import com.ruoyi.common.domain.qo.BaseQO;
import com.ruoyi.common.enums.BaseIsDeletedEnum;
import com.ruoyi.common.mapper.BaseMapper;
import com.ruoyi.common.service.BaseService;
import com.ruoyi.common.utils.PageUtils;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.lang.reflect.ParameterizedType;
import java.util.List;

public abstract class BaseServiceImpl<P extends BasePO, Q extends BaseQO<P>, M extends BaseMapper<P, Q>> implements BaseService<P, Q, M> {
    @Autowired
    private M mapper;
    private Class<P> pClass;
    private Class<Q> qClass;

    @PostConstruct
    @SneakyThrows
    public void init() {
        this.pClass = (Class<P>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        this.qClass = (Class<Q>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
    }
    public List<P> select(Q q){
        return mapper.select(q);
    }

    @Transactional
    @Override
    public int insert(P p){
        p.setId(null);
        return mapper.insert(p);
    }

    @Transactional
    @Override
    public int batchInsert(List<P> ls){
        return mapper.batchInsert(ls);
    }

    @SneakyThrows
    @Override
    public P selectById(Long id){
        Q q = qClass.newInstance();
        q.setId(id);
        List<P> select = mapper.select(q);
        if (select.size() == 0) {
            return null;
        }
        return select.get(0);
    }
    @SneakyThrows
    @Override
    public P selectExistsById(Long id){
        Q q = qClass.newInstance();
        q.setId(id);
        q.setIsDeleted(BaseIsDeletedEnum.EXISTS);
        List<P> select = mapper.select(q);
        if (select.size() == 0) {
            return null;
        }
        return select.get(0);
    }

    @Transactional
    @Override
    public  int update(Q q){
        return mapper.update(q);
    }
    @Override
    @Transactional
    public  int updateSelective(Q q){
        return mapper.updateSelective(q);
    }


    @Override
    public int batchUpdate(List<Q> qs) {
        int i = 0;
        for (Q q : qs) {
            i+=mapper.update(q);
        }
        return i;
    }

    @Override
    @Transactional
    public int batchUpdateSelective(List<Q> qs) {
        int i = 0;
        for (Q q : qs) {
            i+=mapper.updateSelective(q);
        }
        return i;
    }

    @Transactional
    @Override
    public  int delete(Q q){
        return mapper.delete(q);
    }

}
